import tkinter as tk
from tkinter import ttk, scrolledtext, filedialog, messagebox, simpledialog
import asyncio
from api import TongYiAPI
from utils import TextProcessor
from config import MAX_CHUNK_SIZE, MAX_CONCURRENT_REQUESTS
import json
import os
from templates import get_template_names, get_template, format_prompt, get_template_categories, get_templates_by_category, combine_templates, ANALYST_ROLES, combine_roles
from datetime import datetime
import threading
from batch_analyzer import BatchAnalyzerGUI

class APISettingsDialog(tk.Toplevel):
    def __init__(self, parent, api):
        super().__init__(parent)
        self.api = api
        self.title("API设置")
        self.geometry("500x300")
        self.resizable(False, False)
        
        # 创建主框架
        main_frame = ttk.Frame(self, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)  # 改用 pack 布局
        
        # API服务商选择
        provider_frame = ttk.LabelFrame(main_frame, text="服务商选择", padding="5")
        provider_frame.pack(fill=tk.X, pady=(0, 10))
        
        provider_container = ttk.Frame(provider_frame)
        provider_container.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Label(provider_container, text="选择服务商:").pack(side=tk.LEFT, padx=(0, 10))
        self.provider_var = tk.StringVar(value=self.api.provider)
        self.provider_combo = ttk.Combobox(
            provider_container,
            textvariable=self.provider_var,
            values=list(TongYiAPI.PROVIDER_CONFIGS.keys()),
            state="readonly",
            width=20
        )
        self.provider_combo.pack(side=tk.LEFT)
        self.provider_combo.bind('<<ComboboxSelected>>', self.on_provider_change)
        
        # 模型选择
        model_frame = ttk.LabelFrame(main_frame, text="模型选择", padding="5")
        model_frame.pack(fill=tk.X, pady=(0, 10))
        
        model_container = ttk.Frame(model_frame)
        model_container.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Label(model_container, text="选择模型:").pack(side=tk.LEFT, padx=(0, 10))
        self.model_var = tk.StringVar(value=self.api.model)
        self.model_combo = ttk.Combobox(
            model_container,
            textvariable=self.model_var,
            values=list(TongYiAPI.PROVIDER_CONFIGS[self.api.provider]["models"]),
            state="readonly",
            width=30
        )
        self.model_combo.pack(side=tk.LEFT)
        
        # API Key 输入
        key_frame = ttk.LabelFrame(main_frame, text="API Key", padding="5")
        key_frame.pack(fill=tk.X, pady=(0, 10))
        
        key_container = ttk.Frame(key_frame)
        key_container.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Label(key_container, text="API Key:").pack(side=tk.LEFT, padx=(0, 10))
        self.api_key = ttk.Entry(key_container, width=50)
        self.api_key.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        # 设置初始提示文本
        self.placeholder = "请输入通义千问 API Key" if self.api.provider == "通义千问" else "请输入 DeepSeek API Key"
        if self.api.api_key:
            self.api_key.insert(0, self.api.api_key)
        else:
            self.api_key.insert(0, self.placeholder)
            self.api_key.config(foreground='gray')
        
        # 绑定焦点事件
        self.api_key.bind('<FocusIn>', self.on_entry_click)
        self.api_key.bind('<FocusOut>', self.on_focus_out)
        
        # 按钮区域
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=10)
        
        # 让按钮靠左对齐
        ttk.Button(button_frame, text="测试连接", command=self.test_connection).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="保存", command=self.save_settings).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=self.destroy).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="恢复默认", command=self.restore_defaults).pack(side=tk.LEFT, padx=5)
    
    def on_entry_click(self, event):
        """当输入框获得焦点时"""
        if self.api_key.get() == self.placeholder:
            self.api_key.delete(0, tk.END)
            self.api_key.config(foreground='black')
    
    def on_focus_out(self, event):
        """当输入框失去焦点时"""
        if not self.api_key.get():
            self.api_key.insert(0, self.placeholder)
            self.api_key.config(foreground='gray')
    
    def on_provider_change(self, event=None):
        """当切换服务商时更新模型列表和重置 API Key"""
        provider = self.provider_var.get()
        provider_config = TongYiAPI.PROVIDER_CONFIGS.get(provider)
        if provider_config:
            # 更新模型列表
            self.model_combo['values'] = provider_config['models']
            if self.model_var.get() not in provider_config['models']:
                self.model_combo.current(0)
            
            # 更新 placeholder
            self.placeholder = "请输入通义千问 API Key" if provider == "通义千问" else "请输入 DeepSeek API Key"
            self.api_key.delete(0, tk.END)
            self.api_key.insert(0, self.placeholder)
            self.api_key.config(foreground='gray')
    
    def save_settings(self):
        """保存设置"""
        api_key = self.api_key.get().strip()
        # 检查是否是 placeholder
        if api_key == self.placeholder:
            api_key = ""
            
        self.api.api_key = api_key
        self.api.model = self.model_var.get()
        self.api.provider = self.provider_var.get()
        
        # 保存到配置文件
        self.api.save_credentials()
        
        messagebox.showinfo("成功", "设置已保存")
        self.destroy()
    
    def restore_defaults(self):
        """恢复默认设置"""
        self.provider_var.set("通义千问")
        self.model_var.set("deepseek-r1")
        self.api_key.delete(0, tk.END)
    
    async def _test_connection_async(self):
        """异步测试连接"""
        api_key = self.api_key.get().strip()
        if not api_key:
            return False, "请输入 API Key"
        
        # 临时更新API设置进行测试
        temp_api = self.api
        temp_api.api_key = api_key
        temp_api.model = self.model_var.get()
        
        try:
            # 使用简短的测试消息
            result = await temp_api.analyze_text_async(
                "测试", 
                "这是一个简短的API测试"
            )
            return True, "API 连接测试成功！"
        except Exception as e:
            return False, f"连接测试失败：{str(e)}"
    
    def test_connection(self):
        """测试API连接"""
        api_key = self.api_key.get().strip()
        if not api_key:
            messagebox.showerror("错误", "请输入 API Key")
            return
        
        # 显示等待对话框
        self.config(cursor="wait")
        self.update()
        
        try:
            # 临时更新API设置进行测试
            temp_api = TongYiAPI()
            temp_api.api_key = api_key
            temp_api.model = self.model_var.get()
            
            success, message = temp_api.test_connection()
            
            if success:
                messagebox.showinfo("测试成功", "API 连接测试成功！")
            else:
                messagebox.showerror("测试失败", f"API 连接测试失败：{message}")
        except Exception as e:
            messagebox.showerror("错误", f"测试过程出错：{str(e)}")
        finally:
            # 恢复鼠标指针
            self.config(cursor="")

class TemplateInfoDialog(tk.Toplevel):
    """模板说明对话框"""
    def __init__(self, parent, template_name, template_content):
        super().__init__(parent)
        self.title(f"模板说明 - {template_name}")
        self.geometry("600x400")
        
        # 创建主框架
        main_frame = ttk.Frame(self, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建文本显示区域
        text_area = scrolledtext.ScrolledText(main_frame, wrap=tk.WORD, width=60, height=20)
        text_area.pack(fill=tk.BOTH, expand=True)
        
        # 显示模板内容
        text_area.insert(tk.END, template_content)
        text_area.config(state='disabled')  # 设为只读
        
        # 关闭按钮
        ttk.Button(main_frame, text="关闭", command=self.destroy).pack(pady=10)

class TextAnalyzerGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("文本分析工具")
        self.api = TongYiAPI()
        self.text_processor = TextProcessor()
        # 移除 self.history 的初始化
        
        # 设置窗口大小和位置
        window_width = 1200
        window_height = 800
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2
        root.geometry(f"{window_width}x{window_height}+{x}+{y}")
        
        self.setup_ui()
    
    def setup_ui(self):
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))  # 改为 row=0
        
        # 配置网格权重
        self.root.grid_rowconfigure(0, weight=1)  # 改为 rowconfigure(0)
        self.root.grid_columnconfigure(0, weight=1)
        
        # 创建左右分栏
        left_panel = ttk.Frame(main_frame)
        right_panel = ttk.Frame(main_frame)
        left_panel.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 5))
        right_panel.grid(row=0, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(5, 0))
        
        # 配置主框架的网格权重
        main_frame.grid_rowconfigure(0, weight=1)
        main_frame.grid_columnconfigure(0, weight=1)
        main_frame.grid_columnconfigure(1, weight=1)
        
        # 左侧面板 - 输入和分析结果
        # 文本输入区
        input_frame = ttk.LabelFrame(left_panel, text="文本输入", padding="5")
        input_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 5))
        
        self.text_input = scrolledtext.ScrolledText(input_frame, width=50, height=15)
        self.text_input.pack(fill=tk.BOTH, expand=True)
        
        # 分析结果区
        result_frame = ttk.LabelFrame(left_panel, text="分析结果", padding="5")
        result_frame.pack(fill=tk.BOTH, expand=True)
        
        self.result_text = scrolledtext.ScrolledText(result_frame, width=50, height=20)
        self.result_text.pack(fill=tk.BOTH, expand=True)
        
        # 进度条
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(left_panel, variable=self.progress_var, maximum=100)
        self.progress_bar.pack(fill=tk.X, pady=5)
        self.progress_bar.pack_forget()  # 默认隐藏
        
        # 状态标签
        self.status_label = ttk.Label(left_panel, text="")
        self.status_label.pack(anchor=tk.W)
        
        # 底部按钮区
        button_frame = ttk.Frame(left_panel)
        button_frame.pack(fill=tk.X, pady=5)
        
        ttk.Button(button_frame, text="分析", command=self.analyze).pack(side=tk.LEFT, padx=2)
        ttk.Button(button_frame, text="导入文件", command=self.import_file).pack(side=tk.LEFT, padx=2)
        ttk.Button(button_frame, text="批量导入", command=self.import_files).pack(side=tk.LEFT, padx=2)
        ttk.Button(button_frame, text="导出结果", command=self.export_result).pack(side=tk.LEFT, padx=2)
        ttk.Button(button_frame, text="API设置", command=self.show_settings).pack(side=tk.LEFT, padx=2)
        
        # 右侧面板 - 模板选择和角色设置
        # 角色选择区
        role_frame = ttk.LabelFrame(right_panel, text="分析师角色", padding="5")
        role_frame.pack(fill=tk.X, pady=(0, 5))
        
        # 主角色选择
        main_role_frame = ttk.Frame(role_frame)
        main_role_frame.pack(fill=tk.X, pady=2)
        ttk.Label(main_role_frame, text="主要角色:").pack(side=tk.LEFT, padx=5)
        self.main_role_var = tk.StringVar(value="首席策略分析师")
        main_role_combo = ttk.Combobox(
            main_role_frame,
            textvariable=self.main_role_var,
            values=list(ANALYST_ROLES.keys()),
            state="readonly",
            width=25
        )
        main_role_combo.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        main_role_combo.bind('<<ComboboxSelected>>', self.on_main_role_select)  # 添加事件绑定
        
        # 辅助角色选择
        assistant_frame = ttk.Frame(role_frame)
        assistant_frame.pack(fill=tk.X, pady=2)
        
        # 辅助角色标签和列表框容器
        assistant_label_frame = ttk.Frame(assistant_frame)
        assistant_label_frame.pack(fill=tk.X)
        ttk.Label(assistant_label_frame, text="辅助角色:").pack(side=tk.LEFT, padx=5)
        ttk.Label(assistant_label_frame, text="(可多选)").pack(side=tk.LEFT, padx=(0, 5))
        
        # 创建列表框和滚动条的容器
        assistant_list_container = ttk.Frame(assistant_frame)
        assistant_list_container.pack(fill=tk.BOTH, expand=True, padx=5, pady=2)
        
        self.assistant_roles_listbox = tk.Listbox(
            assistant_list_container,
            selectmode=tk.MULTIPLE,
            height=4,  # 增加高度
            exportselection=False
        )
        assistant_scroll = ttk.Scrollbar(
            assistant_list_container,
            orient=tk.VERTICAL,
            command=self.assistant_roles_listbox.yview
        )
        self.assistant_roles_listbox.configure(yscrollcommand=assistant_scroll.set)
        
        self.assistant_roles_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        assistant_scroll.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 初始化辅助角色列表
        self.update_assistant_roles_list()
        
        # 角色操作按钮
        role_buttons = ttk.Frame(role_frame)
        role_buttons.pack(fill=tk.X, pady=2)
        ttk.Button(role_buttons, text="查看主角色", 
                  command=lambda: self.show_role_info(self.main_role_var.get())
                  ).pack(side=tk.LEFT, padx=2)
        ttk.Button(role_buttons, text="查看组合说明", 
                  command=self.show_combined_roles_info
                  ).pack(side=tk.LEFT, padx=2)
        
        # 模板选择区
        template_frame = ttk.LabelFrame(right_panel, text="提示词模板选择", padding="5")
        template_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建模板选择区域
        template_select = ttk.Frame(template_frame)
        template_select.pack(fill=tk.BOTH, expand=True)
        
        # 模板列表区域
        list_frame = ttk.Frame(template_select)
        list_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 5))
        
        # 模板列表标题和说明
        header_frame = ttk.Frame(list_frame)
        header_frame.pack(fill=tk.X)
        ttk.Label(header_frame, text="可选模板:").pack(side=tk.LEFT)
        ttk.Label(header_frame, text="(可多选)").pack(side=tk.LEFT, padx=(5, 0))
        
        # 模板列表和滚动条
        list_container = ttk.Frame(list_frame)
        list_container.pack(fill=tk.BOTH, expand=True)
        
        self.template_listbox = tk.Listbox(list_container, selectmode=tk.MULTIPLE, height=10)
        template_scroll = ttk.Scrollbar(list_container, orient=tk.VERTICAL, command=self.template_listbox.yview)
        self.template_listbox.configure(yscrollcommand=template_scroll.set)
        
        self.template_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        template_scroll.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 添加模板到列表框并绑定选择事件
        for template in get_template_names():
            self.template_listbox.insert(tk.END, template)
        self.template_listbox.bind('<<ListboxSelect>>', self.on_template_select)
        
        # 模板操作按钮
        button_frame = ttk.Frame(template_select)
        button_frame.pack(fill=tk.X, pady=(0, 5))
        ttk.Button(button_frame, text="全选", command=self.select_all_templates).pack(side=tk.LEFT, padx=2)
        ttk.Button(button_frame, text="取消全选", command=self.deselect_all_templates).pack(side=tk.LEFT, padx=2)
        ttk.Button(button_frame, text="查看详情", command=self.show_template_details).pack(side=tk.LEFT, padx=2)
        
        # 模板说明区域
        info_frame = ttk.LabelFrame(template_select, text="模板说明", padding="5")
        info_frame.pack(fill=tk.BOTH, expand=True)
        
        self.template_info = scrolledtext.ScrolledText(info_frame, wrap=tk.WORD, height=8)
        self.template_info.pack(fill=tk.BOTH, expand=True)
        self.template_info.config(state='disabled')
        
        # 自定义提示词输入
        prompt_frame = ttk.LabelFrame(right_panel, text="补充提示词", padding="5")
        prompt_frame.pack(fill=tk.X, pady=(0, 5))

        self.prompt_input = ttk.Entry(prompt_frame)
        self.prompt_input.pack(fill=tk.X, padx=5, pady=5)
    
    def select_all_templates(self):
        """全选所有模板"""
        self.template_listbox.select_set(0, tk.END)
        
    def deselect_all_templates(self):
        """取消全选"""
        self.template_listbox.selection_clear(0, tk.END)
    
    def get_selected_templates(self):
        """获取选中的模板名称列表"""
        selections = self.template_listbox.curselection()
        return [self.template_listbox.get(i) for i in selections]
    
    def analyze(self):
        """分析文本"""
        text = self.text_input.get("1.0", tk.END).strip()
        selected_templates = self.get_selected_templates()
        
        if not text:
            messagebox.showerror("错误", "请输入要分析的文本")
            return
            
        if not selected_templates:
            messagebox.showerror("错误", "请至少选择一个分析模板")
            return
        
        # 组合选中的模板，传入主角色和辅助角色
        prompt = combine_templates(
            selected_templates,
            text,
            self.main_role_var.get(),
            self.get_selected_assistant_roles()
        )
        
        # 清空结果区域
        self.result_text.delete("1.0", tk.END)
        self.result_text.insert(tk.END, "【思考过程】\n")
        
        # 禁用分析按钮
        for widget in self.root.winfo_children():
            if isinstance(widget, ttk.Button) and widget['text'] == "分析":
                widget.configure(state='disabled')
        
        # 创建新线程运行异步分析
        threading.Thread(target=self._run_async_analysis, args=(text, prompt), daemon=True).start()

    def _run_async_analysis(self, text: str, prompt: str):
        """在新线程中运行异步分析"""
        async def run():
            try:
                # 显示进度条
                self.root.after(0, self.progress_bar.pack)
                self.root.after(0, lambda: self.progress_var.set(0))
                
                # 使用流式输出
                async for output_type, content in self.api.analyze_text_stream(text, prompt):
                    # 使用 after 方法更新 UI
                    self.root.after(0, lambda c=content: self._update_result(c))
                
                # 更新状态
                self.root.after(0, lambda: self.status_label.config(text="分析完成"))
                
            except Exception as e:
                error_msg = f"分析过程出错: {str(e)}"
                self.root.after(0, lambda: messagebox.showerror("错误", error_msg))
                self.root.after(0, lambda: self.status_label.config(text="分析失败"))
                self.root.after(0, lambda: self.log_error(error_msg))
            finally:
                # 隐藏进度条
                self.root.after(0, self.progress_bar.pack_forget)
                # 恢复分析按钮
                self.root.after(0, self._enable_analyze_button)
        
        # 创建新的事件循环
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(run())
        loop.close()

    def _update_result(self, content: str):
        """更新结果文本"""
        self.result_text.insert(tk.END, content)
        self.result_text.see(tk.END)
        self.root.update_idletasks()

    def _enable_analyze_button(self):
        """恢复分析按钮状态"""
        for widget in self.root.winfo_children():
            if isinstance(widget, ttk.Button) and widget['text'] == "分析":
                widget.configure(state='normal')

    def log_error(self, error_msg: str):
        """记录错误日志"""
        try:
            with open('error_log.txt', 'a', encoding='utf-8') as f:
                f.write(f"\n[{datetime.now()}] {error_msg}")
        except:
            pass

    def import_file(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
        )
        if file_path:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                self.text_input.delete("1.0", tk.END)
                self.text_input.insert(tk.END, content)
            except Exception as e:
                messagebox.showerror("错误", f"读取文件时出错: {str(e)}")
                
    def export_result(self):
        result = self.result_text.get("1.0", tk.END).strip()
        if not result:
            messagebox.showerror("错误", "没有可导出的结果")
            return
            
        file_path = filedialog.asksaveasfilename(
            defaultextension=".txt",
            filetypes=[("文本文件", "*.txt"), ("Markdown文件", "*.md")]
        )
        
        if file_path:
            file_format = "markdown" if file_path.endswith(".md") else "txt"
            if self.text_processor.save_to_file(result, file_path, file_format):
                messagebox.showinfo("成功", "结果已成功导出")
            else:
                messagebox.showerror("错误", "导出结果时出错")

    def show_settings(self):
        settings_dialog = APISettingsDialog(self.root, self.api)
        settings_dialog.transient(self.root)  # 设置为主窗口的子窗口
        settings_dialog.grab_set()  # 模态对话框
        self.root.wait_window(settings_dialog)  # 等待对话框关闭

    def on_template_select(self, event):
        """当选择模板时更新说明信息"""
        selections = self.template_listbox.curselection()
        if selections:
            # 获取最后选择的模板
            template_name = self.template_listbox.get(selections[-1])
            template_content = get_template(template_name)
            
            # 更新说明文本
            self.template_info.config(state='normal')
            self.template_info.delete(1.0, tk.END)
            
            # 提取模板的主要内容（去掉文本内容标记）
            template_desc = template_content.split("\n\n文本内容：")[0]
            self.template_info.insert(tk.END, template_desc)
            self.template_info.config(state='disabled')
    
    def show_template_details(self):
        """显示模板详细信息"""
        selections = self.template_listbox.curselection()
        if selections:
            template_name = self.template_listbox.get(selections[-1])
            template_content = get_template(template_name)
            
            # 创建详情对话框
            TemplateInfoDialog(self.root, template_name, template_content)
    
    def on_main_role_select(self, event):
        """当选择主角色时更新辅助角色列表"""
        self.update_assistant_roles_list()
        self.show_role_info(self.main_role_var.get())
    
    def update_assistant_roles_list(self):
        """更新辅助角色列表"""
        main_role = self.main_role_var.get()
        self.assistant_roles_listbox.delete(0, tk.END)
        for role in ANALYST_ROLES.keys():
            if role != main_role:
                self.assistant_roles_listbox.insert(tk.END, role)
    
    def get_selected_assistant_roles(self):
        """获取选中的辅助角色列表"""
        selections = self.assistant_roles_listbox.curselection()
        return [self.assistant_roles_listbox.get(i) for i in selections]
    
    def show_role_info(self, role_name):
        """显示角色详细信息"""
        if role_name in ANALYST_ROLES:
            role = ANALYST_ROLES[role_name]
            info = f"""【{role['title']}】

经验：{role['experience']}

背景：{role['background']}

专业特长：
{chr(10).join(f'• {specialty}' for specialty in role['specialties'])}

分析风格：
{role['analysis_style']}"""
            
            # 创建详情对话框
            dialog = tk.Toplevel(self.root)
            dialog.title(f"角色说明 - {role_name}")
            dialog.geometry("500x300")
            
            text_area = scrolledtext.ScrolledText(dialog, wrap=tk.WORD, width=50, height=15)
            text_area.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
            text_area.insert(tk.END, info)
            text_area.config(state='disabled')
            
            ttk.Button(dialog, text="关闭", command=dialog.destroy).pack(pady=5)
    
    def show_combined_roles_info(self):
        """显示角色组合说明"""
        main_role = self.main_role_var.get()
        assistant_roles = self.get_selected_assistant_roles()
        
        combined_prompt = combine_roles(main_role, assistant_roles)
        
        dialog = tk.Toplevel(self.root)
        dialog.title("角色组合说明")
        dialog.geometry("600x400")
        
        text_area = scrolledtext.ScrolledText(dialog, wrap=tk.WORD, width=60, height=20)
        text_area.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        text_area.insert(tk.END, combined_prompt)
        text_area.config(state='disabled')
        
        ttk.Button(dialog, text="关闭", command=dialog.destroy).pack(pady=5)

    def import_files(self):
        """打开批量分析窗口"""
        batch_window = tk.Toplevel(self.root)
        batch_window.title("批量文本分析")
        BatchAnalyzerGUI(batch_window)
        batch_window.transient(self.root)
        batch_window.grab_set()

    def get_analysis_prompt(self, text: str) -> str:
        """获取分析提示词"""
        return combine_templates(
            self.get_selected_templates(),
            text,
            self.main_role_var.get(),
            self.get_selected_assistant_roles()
        )

class BatchAnalysisDialog(tk.Toplevel):
    def __init__(self, parent, file_paths, main_gui):
        super().__init__(parent)
        self.title("批量文件分析")
        self.geometry("800x600")
        self.file_paths = file_paths
        self.main_gui = main_gui
        
        # 创建文件列表
        list_frame = ttk.LabelFrame(self, text="待分析文件", padding="5")
        list_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 文件列表
        self.file_list = ttk.Treeview(
            list_frame,
            columns=("文件名", "状态", "进度"),
            show="headings"
        )
        self.file_list.heading("文件名", text="文件名")
        self.file_list.heading("状态", text="状态")
        self.file_list.heading("进度", text="进度")
        
        # 添加文件到列表
        for path in file_paths:
            self.file_list.insert("", tk.END, values=(os.path.basename(path), "等待中", "0%"))
        
        self.file_list.pack(fill=tk.BOTH, expand=True)
        
        # 控制按钮
        button_frame = ttk.Frame(self)
        button_frame.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Button(button_frame, text="开始分析", command=self.start_analysis).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="停止", command=self.stop_analysis).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="导出所有结果", command=self.export_all_results).pack(side=tk.LEFT, padx=5)
        
        # 存储分析结果
        self.results = {}
        self.is_running = False
    
    async def analyze_file(self, file_path, item_id):
        """分析单个文件"""
        try:
            # 更新状态
            self.file_list.set(item_id, "状态", "分析中")
            
            # 读取文件内容
            content = self.read_file_content(file_path)
            
            # 使用主界面的模板和设置进行分析
            prompt = combine_templates(
                self.main_gui.get_selected_templates(),
                content,
                self.main_gui.main_role_var.get(),
                self.main_gui.get_selected_assistant_roles()
            )
            
            # 分析文本
            result = ""
            async for output_type, content in self.main_gui.api.analyze_text_stream(content, prompt):
                result += content
                # 更新进度
                self.file_list.set(item_id, "进度", "分析中...")
            
            # 保存结果
            self.results[file_path] = result
            self.file_list.set(item_id, "状态", "完成")
            self.file_list.set(item_id, "进度", "100%")
            
        except Exception as e:
            self.file_list.set(item_id, "状态", f"错误: {str(e)}")
            self.file_list.set(item_id, "进度", "失败")
    
    def read_file_content(self, file_path):
        """根据文件类型读取内容"""
        ext = os.path.splitext(file_path)[1].lower()
        
        if ext == '.txt':
            with open(file_path, 'r', encoding='utf-8') as f:
                return f.read()
        elif ext == '.docx':
            # 需要安装 python-docx
            from docx import Document
            doc = Document(file_path)
            return '\n'.join(p.text for p in doc.paragraphs)
        elif ext == '.pdf':
            # 需要安装 PyPDF2
            from PyPDF2 import PdfReader
            reader = PdfReader(file_path)
            return '\n'.join(page.extract_text() for page in reader.pages)
        else:
            raise ValueError(f"不支持的文件类型: {ext}")
    
    def export_all_results(self):
        """导出所有分析结果"""
        if not self.results:
            messagebox.showwarning("提示", "没有可导出的结果")
            return
            
        export_dir = filedialog.askdirectory(title="选择导出目录")
        if not export_dir:
            return
            
        try:
            for file_path, result in self.results.items():
                base_name = os.path.splitext(os.path.basename(file_path))[0]
                result_path = os.path.join(export_dir, f"{base_name}_分析结果.txt")
                
                with open(result_path, 'w', encoding='utf-8') as f:
                    f.write(result)
            
            messagebox.showinfo("成功", "所有结果已导出")
        except Exception as e:
            messagebox.showerror("错误", f"导出结果时出错: {str(e)}")

    def start_analysis(self):
        """开始批量分析"""
        if self.is_running:
            return
        
        self.is_running = True
        threading.Thread(target=self._run_analysis, daemon=True).start()

    def stop_analysis(self):
        """停止分析"""
        self.is_running = False

    def _run_analysis(self):
        """在新线程中运行分析"""
        async def run():
            for item in self.file_list.get_children():
                if not self.is_running:
                    break
                    
                file_path = next(
                    path for path in self.file_paths 
                    if os.path.basename(path) == self.file_list.item(item)['values'][0]
                )
                
                await self.analyze_file(file_path, item)
        
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(run())
        loop.close()
        
        self.is_running = False 